/*
 * $Id: EmailServiceImpl.java 3 2011-12-26 07:48:43Z forwardly@hotmail.com $
 * 
 * Copyright (c) 2001-2008 Accentrix Company Limited. All Rights Reserved.
 * 
 * Accentrix Company Limited. ("Accentrix") retains copyright on all text, source
 * and binary code contained in this software and documentation. Accentrix grants
 * Licensee a limited license to use this software, provided that this copyright
 * notice and license appear on all copies of the software. The software source
 * code is provided for reference purposes only and may not be copied, modified 
 * or distributed.
 * 
 * THIS SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS," WITHOUT ANY WARRANTY OF
 * ANY KIND UNLESS A SEPARATE WARRANTIES IS PURCHASED FROM ACCENTRIX AND REMAINS
 * VALID.  ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. ACCENTRIX SHALL NOT BE LIABLE
 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING OR MODIFYING THE
 * SOFTWARE OR ITS DERIVATIVES.
 * 
 * IN NO EVENT WILL ACCENTRIX BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
 * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES,
 * HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE
 * USE OF OR INABILITY TO USE SOFTWARE, EVEN IF ACCENTRIX HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 */
package com.lightsaber.trade.as.service.email.impl;

import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.lightsaber.trade.as.dao.email.EmailTemplateDao;
import com.lightsaber.trade.as.entity.email.EmailTemplate;
import com.lightsaber.trade.as.service.email.EmailService;

@Service
public class EmailServiceImpl extends EmailService {

    private final static Logger log = LoggerFactory.getLogger(EmailServiceImpl.class);

    @Autowired
    private EmailTemplateDao emailTemplateDao;

    @Value("#{appProperties['email.protocol']}")
    private String protocol;

    @Value("#{appProperties['email.host']}")
    private String host;

    @Value("#{appProperties['email.username']}")
    private String user;

    @Value("#{appProperties['email.password']}")
    private String password;

    @Value("#{appProperties['email.encoding']}")
    private String charset;

    @Override
    protected String getContent(final String emailType, final Map<String, String> values) {

        List<EmailTemplate> templates = emailTemplateDao.findBy("type", emailType);

        if (templates.isEmpty()) {
            log.warn("not found any EmailTemplate by type: {}", emailType);
            return "";
        }

        EmailTemplate emailTemplate = templates.get(0);

        String template = emailTemplate.getTemplate();

        log.info("Email Template: {}", template);

        Velocity.init();

        VelocityContext context = new VelocityContext();

        Set<Map.Entry<String, String>> entrySet = values.entrySet();
        for (Map.Entry<String, String> entry : entrySet) {
            context.put(entry.getKey(), entry.getValue());
        }

        String logTag = "logTag";

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(byteArrayOutputStream));

        Velocity.evaluate(context, writer, logTag, template);

        try {
            writer.flush();
            writer.close();
            return byteArrayOutputStream.toString();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }

        return null;
    }

    @Override
    protected void doSendEmail(final String from, final String[] tos, final String subject,
            final String content) throws Exception {
        log.info("Sending mail...");

        Properties props = new Properties();

        log.info("protocol: {}", protocol);
        log.info("host: {}", host);
        log.info("user: {}", user);
        log.info("charset: {}", charset);

        props.setProperty("mail.transport.protocol", protocol);
        props.setProperty("mail.host", host);
        props.setProperty("mail.user", user);
        props.setProperty("mail.password", password);
        props.setProperty("mail.mime.charset", charset);

        Session mailSession = Session.getDefaultInstance(props, null);
        mailSession.setDebug(true);
        Transport transport = mailSession.getTransport();

        MimeMessage message = new MimeMessage(mailSession);
        message.setSubject(subject);
        message.setFrom(new InternetAddress(from));

        message.setSentDate(new Date());

        for (String to : tos) {
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
        }

        //
        // This HTML mail have to 2 part, the BODY and the embedded image
        //
        MimeMultipart multipart = new MimeMultipart("related");

        // first part (the html)
        BodyPart messageBodyPart = new MimeBodyPart();
        messageBodyPart.setContent(content, "text/html; charset=UTF-8");

        // add it
        multipart.addBodyPart(messageBodyPart);

        // put everything together
        message.setContent(multipart);

        transport.connect();
        transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO));
        transport.close();
    }
}
